package thread;

import java.util.Scanner;

public class Demo20 {
    // volatile 只能修饰变量
    private volatile static int count=0;//用volatile解决不了问题
    //volatile 是一个线程读 一个线程写的问题  synchronized是在内存中变量覆盖的问题
    public static void main2(String[] args) throws InterruptedException {
        Thread t1=new Thread(()->{
           for(int i=0;i<5000;i++){
               count++;
           }
        });
        Thread t2=new Thread(()->{
            for(int i=0;i<5000;i++){
                count++;
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("count的值为:"+count);
    }
    //private static int flag=0;
    private volatile static int flag=0;
    //volatile t2修改 t1就能及时看到
    //volatile 和 synchronized 有着本质的区别.synchronized 能够保证原⼦性, volatile 保证的是内存可⻅性 让内存看见变量是易变的
    public static void main1(String[] args) {
        Thread t1=new Thread(()->{
           while (flag==0){
               /*try {
                   Thread.sleep(1);//加入sleep(1)相比于 load flag的操作时间消耗不少 编译器优化 load flag 的操作没有意义
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }*///使用sleep可以解决内存可见性问题 但是效率太慢 引入volatile关键字解决
           }
            System.out.println("t1线程结束");
        });
        Thread t2=new Thread(()->{
            Scanner scanner=new Scanner(System.in);
            System.out.println("请输入flag的值：");
            flag=scanner.nextInt();
        });
        t1.start();
        t2.start();
        /*一个线程读取 一个线程修改
        * 修改线程的修改值并没有被读取线程读到
        * 编译器优化导致的
        * 内存可见性问题
        * */
    }
}
